from qturboframe.lib.report.log import logger
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.utils.CustomError.custom_error import CustomError
from qturboframe.lib.utils.CustomError.custom_exception import CustomException
from qturboframe.public_ui.base_element import BaseElement
from qturboframe.public_ui.h_ui.base_table import BaseTable


class TreeGrid(BaseElement):
    '''
    hui的树表格操作

    :Attributes:
     - page: 当前表格的分页栏对象
    '''

    def __init__(self, element_para, father=None, timeout=5):
        super().__init__(element_para, father, timeout)
        self.head_table = BaseTable(
            {'xpath': './div/div[@class=\'h-editgird-header\']/table'}, self._element, self.timeout)
        self.body_table = BaseTable(
            {'xpath': './div/div[@class=\'h-editgird-body\']/table'}, self._element, self.timeout)

    def get_cell(self, tree_node, title_name):
        '''
        根据单元格列名和树表格节点查找树表格的单元格

        :Args:
         - tree_node: 树形结构顺序点击的节点值，例：'XX1/XX2/XX3'
         - title_name: 查找的单元格列名

        :Returns:
            返回查找的单元格

        :Example:
         - 例: cell = treegrid.get_cell('组织/部门/员工A', '工号')
        '''
        node_list = tree_node.split('/')
        title_list = self.head_table.get_title_list()
        # 打开树枝表格
        if len(node_list) > 1:
            last_value = node_list[-1]
            del node_list[-1]
            temp_table = self.body_table
            for va in node_list:
                if temp_table is not None:
                    up_table = self.__open_tree_table(title_list, temp_table, va)
                    temp_table = up_table
        else:
            temp_table = self.body_table
            last_value = node_list[0]
        # 获取树叶节点单元格
        cell = self.__get_leaf_cell(title_list, temp_table, last_value)
        # 获取单元格
        title_index = title_list.index(title_name)
        cell_list = cell.find_elements_by_attribute('xpath', './parent::tr/td', timeout=self.timeout)
        return cell_list[title_index]

    def select_rows(self, tree_node_list):
        '''
        树表格行勾选

        :Args:
         - tree_node_list: 树形结构顺序点击的节点值列表，例：['XX1/XX2/XX3', 'XX1/XX4/XX5']

        :Example:
         - 例: treegrid.select_rows(['根节点1/子节点1/叶子节点1','根节点2/子节点2/叶子节点2'])
        '''
        re_choosed = 'h-checkbox-checked'
        if isinstance(tree_node_list, str):
            tree_node_list = tree_node_list.split(',')
        for tree_node in tree_node_list:
            if tree_node == '-':
                continue
            node_list = tree_node.strip().split('/')
            title_list = self.head_table.get_title_list()
            # 打开树枝表格
            if len(node_list) > 1:
                last_value = node_list[-1]
                del node_list[-1]
                temp_table = self.body_table
                for va in node_list:
                    if temp_table is not None:
                        up_table = self.__open_tree_table(title_list, temp_table, va)
                        temp_table = up_table
            else:
                temp_table = self.body_table
                last_value = node_list[0]
            # 获取树叶节点单元格
            cell = self.__get_leaf_cell(title_list, temp_table, last_value)
            # 节点勾选
            span = cell.find_element_by_attribute(
                'css selector', 'label.h-checkbox-wrapper>span.h-checkbox', timeout=self.timeout)
            if re_choosed not in span.get_attribute('class').split(' '):
                span.secure_click()

    def check_cell_exist(self, tree_node, title_name):
        '''
        根据单元格列名和树表格节点检查树表格的单元格是否存在

        :Args:
         - tree_node: 树形结构顺序点击的节点值，例：'XX1/XX2/XX3'
         - title_name: 查找的单元格列名

        :Returns:
            返回查找的单元格

        :Example:
         - 例: treegrid.check_cell_exist('组织/部门/员工A', '工号')
        '''
        node_list = tree_node.split('/')
        title_list = self.head_table.get_title_list()
        # 打开树枝表格
        if len(node_list) > 1:
            last_value = node_list[-1]
            del node_list[-1]
            temp_table = self.body_table
            for va in node_list:
                if temp_table is not None:
                    up_table = self.__open_tree_table(title_list, temp_table, va)
                    temp_table = up_table
        else:
            temp_table = self.body_table
            last_value = node_list[0]
        # 获取树叶节点单元格
        cell = self.__get_leaf_cell(title_list, temp_table, last_value)
        # 获取单元格
        title_index = title_list.index(title_name)
        cell_list = cell.find_elements_by_attribute('xpath', './parent::tr/td', timeout=self.timeout)
        if not cell_list[title_index]:
            raise SeleniumError(CustomError.Error_EQ0302102_Tree_Grid_Cannot_Find,'未找到表格单元格，校验失败！')

    def check_rows_exist(self, tree_node_list):
        '''
        根据树表格节点检查树表格行是否存在

        :Args:
         - tree_node_list: 树形结构顺序点击的节点值列表，例：['XX1/XX2/XX3', 'XX1/XX4/XX5']

        :Example:
         - 例: treegrid.select_rows(['根节点1/子节点1/叶子节点1','根节点2/子节点2/叶子节点2'])
        '''
        for tree_node in tree_node_list:
            node_list = tree_node.split('/')
            title_list = self.head_table.get_title_list()
            # 打开树枝表格
            if len(node_list) > 1:
                last_value = node_list[-1]
                del node_list[-1]
                temp_table = self.body_table
                for va in node_list:
                    if temp_table is not None:
                        up_table = self.__open_tree_table(title_list, temp_table, va)
                        temp_table = up_table
            else:
                temp_table = self.body_table
                last_value = node_list[0]
            # 获取树叶节点单元格
            cell = self.__get_leaf_cell(title_list, temp_table, last_value)
            if not cell:
                raise SeleniumError(CustomError.Error_EQ0302102_Tree_Grid_Cannot_Find,'未找到 {} 节点，表格行校验不通过！'.format(last_value))

    def __open_tree_table(self, title_list, node_table:BaseTable, node_name):
        re_open = 'h-editgird-icon-click-expanded'
        node_cell_list = node_table.get_cell_list(len(title_list), 1)
        for cell in node_cell_list:
            if cell.text == node_name:
                logger.info('打开节点：' + node_name)
                click_i = cell.find_element_by_attribute(
                    'css selector', 'i.h-editgird-icon-click', timeout=self.timeout)
                if re_open not in click_i.get_attribute('class').split(' '):
                    click_i.secure_click()
                next_tr = cell.find_elements_by_attribute(
                    'xpath', './parent::tr/following-sibling::tr', timeout=self.timeout)[0]
                next_table = next_tr.find_element_by_attribute('xpath', './td/table', timeout=self.timeout)
                return BaseTable(next_table)
        else:
            raise SeleniumError(CustomError.Error_EQ0302102_Tree_Grid_Cannot_Find,'未找到 {} 节点！'.format(node_name))

    def __get_leaf_cell(self, title_list, node_table:BaseTable, node_name):
        node_cell_list = node_table.get_cell_list(len(title_list), 1)
        for cell in node_cell_list:
            if cell.text == node_name:
                return cell
        else:
            return None


